/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.ly.ocw.web.weixin;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.mapper.JsonMapper;

import com.ly.ocw.comm.Error;
import com.ly.ocw.entity.CrmMember;
import com.ly.ocw.entity.weixin.WeixinCard;
import com.ly.ocw.entity.weixin.WeixinUserCard;
import com.ly.ocw.exception.ServerException;
import com.ly.ocw.service.CrmMemberService;
import com.ly.ocw.service.VcodeService;
import com.ly.ocw.service.weixin.WeixinAccessTokenService;
import com.ly.ocw.service.weixin.WeixinCardApiTicketService;
import com.ly.ocw.service.weixin.WeixinCardService;
import com.ly.ocw.service.weixin.WeixinUserCardService;
import com.ly.ocw.service.weixin.WeixinUserInfoService;
import com.ly.ocw.vo.wx.card.AddCardListVo;
import com.ly.ocw.vo.wx.card.CardExt;
import com.ly.ocw.vo.wx.card.CardVo;

/**
 * 商城controller
 * 
 * @author peter
 */
@Controller
@RequestMapping(value = "/card")
public class CardController {

	
	private static DecimalFormat df = new DecimalFormat("0000.##");
	
	private static JsonMapper mapper = JsonMapper.nonEmptyMapper();

	private static Logger logger = LoggerFactory.getLogger(CardController.class);

	@Autowired
	private WeixinCardService weixinCardService;

	@Autowired
	private WeixinUserCardService weixinUserCardService;

	@Autowired
	private WeixinAccessTokenService weixinAccessTokenService;

	@Autowired
	private WeixinCardApiTicketService weixinCardApiTicketService;

	@Autowired
	private WeixinUserInfoService weixinUserInfoService;

	@Autowired
	private CrmMemberService crmMemberService;

	@Autowired
	private VcodeService vcodeService;

	// to 绑定会员卡页面
	@RequestMapping(method = RequestMethod.GET)
	public String list(HttpServletRequest request, HttpServletResponse response, Model model) {

		// https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb02a7add18dd8b2b&redirect_uri=http://wx.wolft.cn/boycard/&response_type=code&scope=snsapi_userinfo&state=langya#wechat_redirect
		/*
		 * // 获取用户微信信息 String code = request.getParameter("code"); String state
		 * = request.getParameter("state"); String openId =
		 * request.getParameter("openId");
		 * 
		 * // 如果没有OpenId， 从微信服务器拉取用户信息
		 * 
		 * if (StringUtils.isBlank(openId)) { openId =
		 * weixinUserInfoService.receiveWeixinUserInfo(code); }
		 * 
		 * 
		 * logger.info("进入系统 ==========>{code：" + code + "}"); Subject
		 * currentUser = SecurityUtils.getSubject();
		 * 
		 * if (!currentUser.isAuthenticated()) {
		 * logger.info("logine---------未登录"); // 登录系统
		 * logger.info("logine---------已绑定微信，根据openId登录系统：openId:" + openId);
		 * WeixinOAuthToken token = new WeixinOAuthToken(code, state, false,
		 * null); token.setRememberMe(true); currentUser.login(token); } else {
		 * logger.info("logine---------已登录"); }
		 */
		return "redirect:/card/addCard";

	}

	@RequestMapping(value = "addCard", method = RequestMethod.GET)
	public String addCard(HttpServletRequest request, HttpServletResponse response, Model model) {

		List<WeixinCard> cardList = weixinCardService.getAllUsedCardsByWeixinId();

		logger.info("card size :" + cardList.size());

		model.addAttribute("cardList", cardList);
		return "card/addCard";

	}

	// 用户选择一个会员卡，为用户开通会员卡
	// 为addCard JS接口 准备签名和数据（调用页面JS
	// addCard接口，需要signature和会员卡信息，通过ajax将数据传给页面，页面使用该数据作为addCard的参数）
	@RequestMapping(value = "ajax/cardsign/{cardId}/{mobilePhone}/{valiCode}", method = RequestMethod.POST)
	@ResponseBody
	public AddCardListVo cardsign(@PathVariable("cardId") String cardId, @PathVariable("mobilePhone") String mobilePhone, @PathVariable("valiCode") String valiCode, Model model) {
		AddCardListVo result = new AddCardListVo();
		CardVo card = new CardVo();

		try {
			// 验证 手机验证码
			//if (!vcodeService.validate(mobilePhone, valiCode)) {
			//	throw new ServerException("10001", "验证码错误，您输入的验证码：" + valiCode);
			//}

			// 获得卡券 api_ticket
			String ticket = weixinCardApiTicketService.getCardApiTicket();
			// String cardId = "pMBADj-KaT_LCVKVH7isG47hDO-s";

			String timestamp = System.currentTimeMillis() / 1000 + "";

			// String code = genCode();// 生产随机code(string 20)

			// 从CRM获取会员信息,并保存会员信息
//			CrmMember crmMemeber = crmMemberService.receiveMemberInfo(cardId, mobilePhone);
			
			//获取一个随机的会员信息，仅仅为了演示（Demo）
			CrmMember crmMemeber = crmMemberService.receiveRandomMemberInfo(cardId, mobilePhone);
			
			String code = crmMemeber.getCardNumber();
			String signature = sign(ticket, code, timestamp, cardId);

			CardExt cardExt = new CardExt();
			cardExt.setCode(code);
			// cardExt.setOpenid("");
			cardExt.setSignature(signature);
			cardExt.setTimestamp(timestamp);

			card.setCardId(cardId);
			card.setCardExt(mapper.toJson(cardExt));

			result.getCardList().add(card);

			result.setSuccess(true);

			WeixinUserCard weixinUserCard = new WeixinUserCard();
			weixinUserCard.setCardId(cardId);
			weixinUserCard.setCardNumber(code);
			weixinUserCard.setCreateDate(new Date());
			weixinUserCard.setSignature(signature);
			weixinUserCard.setTimestamp(timestamp);
			// weixinUserCard.setOpenid(getCurrentUser().getOpenid());
			weixinUserCard.setMobilephone(mobilePhone);

			weixinUserCardService.save(weixinUserCard);

		} catch (ServerException e) {
			if(!Error._50001.equals(e.getCode())){
				logger.error("---------- jssdk addCard 接入失败   --------", e);
			}
			result.setSuccess(false);
			result.setErrmsg(e.getMessage());
		} catch (Exception e) {
			logger.error("---------- jssdk addCard 接入失败   --------", e);
			result.setSuccess(false);
			result.setErrmsg("绑定会员卡失败，服务器繁忙！");
		}
		return result;
	}

	// ----------------------------------------------private -----------------
	/**
	 * 生成随机code ###
	 * 
	 * @return
	 */
	private String genCode() {
		String code = "";
		Random r = new Random();
		code = df.format(r.nextInt(1000)) + "" + df.format(r.nextInt(1000)) + "" + df.format(r.nextInt(1000)) + "" + df.format(r.nextInt(1000));

		return code;
	}

	/**
	 * code=jonyqin_1434008071， timestamp=1404896688，
	 * card_id=pjZ8Yt1XGILfi-FUsewpnnolGgZk，
	 * api_ticket=ojZ8YtyVyr30HheH3CM73y7h4jJE ， nonce_str=jonyqin
	 * 则signature=sha1(pjZ8Yt1XGILfi-
	 * FUsewpnnolGgZkjonyqin_1434008071ojZ8YtyVyr30HheH3CM73y7h4jJE1404896688jonyqin
	 * )=4F76593A4245644FAE4E1BC940F6422A0C3EC03E。
	 * 
	 * 
	 * @param ticket
	 * @param code
	 * @param timestamp
	 * @param cardId
	 * @return
	 */
	private String sign(String ticket, String code, String timestamp, String cardId) {
		String signature = "";

		String[] str = { ticket, timestamp, cardId, code };

		Arrays.sort(str); // 字典序排序
		String bigStr = str[0] + str[1] + str[2] + str[3];

		logger.info("bigStr:" + bigStr);
		/*
		 * try { signature = sha1(bigStr); } catch (NoSuchAlgorithmException e)
		 * { e.printStackTrace(); }
		 */
		// SHA1加密
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(bigStr.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		logger.info("signature:" + signature);
		return signature;
	}

	private String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

}
